"use strict";
const path = require("path");
const Package = require("@zreact-cli/package");
const log = require("@zreact-cli/log");
const { spawn } = require("@zreact-cli/utils");

const SETTINGS = {
  init: "@zreact-cli/init",
  // init: "@imooc-cli/init",
};

const cacheDir = "dependencies";

async function exec() {
  //1. targetPath -> modulePath
  let targetPath = process.env.CLI_TARGETPATH;
  const homePath = process.env.CLI_HOME;
  const cmdObj = arguments[arguments.length - 1];
  const packageName = SETTINGS[cmdObj.name()];
  const packageVersion = "latest";

  log.verbose("targetPath", targetPath);
  log.verbose("homePath", homePath);
  let storeDir = "";
  let pkg;
  if (!targetPath) {
    targetPath = path.resolve(homePath, cacheDir);
    storeDir = path.resolve(targetPath, "node_modules");
    //2 modulePath -> Package(npm 模块)
    //本地缓存获取
    pkg = new Package({
      targetPath,
      storePath: homePath,
      packageName,
      packageVersion,
    });
    //4 Package.update/ install
    if (await pkg.exists()) {
      //更新package
      await pkg.update();
    } else {
      //安装package
      await pkg.install();
    }
  } else {
    //指定路径获取
    pkg = new Package({
      targetPath,
      packageName,
      packageVersion,
    });
  }
  //3 Package.getRootFile(获取入口文件)
  const rootFile = pkg.getRootFilePath();
  if (rootFile) {
    try {
      //改造成node子进程中调用
      // require(rootFile).call(null, Array.from(arguments));
      //node 多进程方式
      const args = Array.from(arguments);
      const cmd = args[args.length - 1];
      const o = Object.create(null);
      //过滤多余数据
      Object.keys(cmd).forEach((key) => {
        if (key === "_optionValues") {
          //解析values
          Object.keys(cmd[key]).forEach((valKey) => {
            o[valKey] = cmd[key][valKey];
          });
        }
        if (
          cmd.hasOwnProperty(key) &&
          !key.startsWith("_") &&
          key !== "parent"
        ) {
          o[key] = cmd[key];
        }
      });
      args[args.length - 1] = o;
      const code = `require('${rootFile}').call(null, ${JSON.stringify(args)})`;
      //spawn流的形式
      const child = spawn("node", ["-e", code], {
        cwd: process.cwd(),
        stdio: "inherit",
      });
      child.on("error", (e) => {
        log.error(e.message);
        process.exit();
      });
      child.on("exit", (e) => {
        log.verbose("执行成功", e);
        process.exit(e);
      });
    } catch (error) {
      log.error(error.message);
    }
  }
}

module.exports = exec;
